package cn.org.donald.service.impl;

import cn.org.donald.framework.constant.InfoConstant;
import cn.org.donald.framework.handler.ServiceException;
import cn.org.donald.framework.pojo.dto.IdsDto;
import cn.org.donald.framework.pojo.dto.Page;
import cn.org.donald.framework.pojo.dto.PageDto;
import cn.org.donald.framework.util.BeanUtil;
import cn.org.donald.mapper.FeatureMapper;
import cn.org.donald.mapper.GameFeatureMapper;
import cn.org.donald.mapper.TypeMapper;
import cn.org.donald.pojo.dto.game.AddGameDto;
import cn.org.donald.pojo.dto.game.GameDto;
import cn.org.donald.pojo.dto.game.QueryDto;
import cn.org.donald.pojo.dto.game.QueryGameDto;
import cn.org.donald.pojo.entity.game.Feature;
import cn.org.donald.pojo.entity.game.Game;
import cn.org.donald.mapper.GameMapper;
import cn.org.donald.pojo.entity.game.GameFeature;
import cn.org.donald.pojo.entity.game.Type;
import cn.org.donald.pojo.vo.GameVo;
import cn.org.donald.service.game.GameService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Donald
 * @since 2020-12-12
 */
@Service(interfaceClass = GameService.class, version = "1.0.0", group = "donald")
public class GameServiceImpl extends ServiceImpl<GameMapper, Game> implements GameService {

    @Autowired
    private GameMapper gameMapper;

    @Autowired
    private GameFeatureMapper gameFeatureMapper;

    @Autowired
    private TypeMapper typeMapper;

    @Autowired
    private FeatureMapper featureMapper;

    /**单机called*/
    private final String[] ONLINE_NAME_OFF = {"单机","本地"};

    /**单机value*/
    private final Integer ONLINE_VALUE_OFF = 0;

    /**网游called*/
    private final String[] ONLINE_NAME_ON = {"网游","在线","网络游戏"};

    /**网游value*/
    private final Integer ONLINE_VALUE_ON = 1;


    /**端游called*/
    private final String[] PLATFORM_NAME_PC = {"端游","PC","电脑","电脑游戏"};

    /**端游value*/
    private final Integer PLATFORM_VALUE_PC = 0;

    /**手游called*/
    private final String[] PLATFORM_NAME_MOBILE = {"手游","安卓","IOS","手机游戏"};

    /**手游value*/
    private final Integer PLATFORM_VALUE_MOBILE = 1;


    /**
     * 添加游戏
     *
     * @param gameDto
     * @return
     */
    @Override
    @Transactional( rollbackFor = Exception.class)
    public boolean add(GameDto gameDto) {
        // 判断feature特性存不存在
        List<Feature> featureList = gameDto.getFeatureList();
        featureList.removeIf(feature -> !featureMapper.isExistById(feature.getId()));
        if (featureList.isEmpty()){
            throw new ServiceException("特性id全部不存在!");
        }

        // 添加游戏记录
        Game game = new Game();
        BeanUtil.copyProperties(gameDto,game);
        int insert = gameMapper.insert(game);
        if (insert<=0){
            throw new ServiceException(InfoConstant.ROLLBACK);
        }
        Long gameId = game.getId();

        // 添加game-feature关联表
        int sum = featureList.stream().mapToInt(feature -> {
            GameFeature gameFeature = new GameFeature();
            gameFeature.setGameId(gameId);
            gameFeature.setFeatureId(feature.getId());
            return gameFeatureMapper.insert(gameFeature);
        }).sum();

        if (sum != featureList.size()){
            throw new ServiceException(InfoConstant.ROLLBACK);
        }
        return true;

    }

    /**
     * 分页查询游戏列表
     *
     * @param pageDto
     * @return
     */
    @Override
    public IPage<GameVo> findPage(PageDto<Game> pageDto) {
        QueryWrapper<Game> queryWrapper = null;
        Game query = pageDto.getQuery();
        if (!BeanUtil.isEmptyOrClassFieldAllEmpty(query)){
            queryWrapper = new QueryWrapper<>(query);
        }
        IPage<Game> gameIPage = gameMapper.selectPage(pageDto, queryWrapper);
        List<Game> records = gameIPage.getRecords();
        List<GameVo> list = new ArrayList<>(records.size());
        records.forEach(record -> {
            GameVo gameVo = new GameVo();
            BeanUtil.copyProperties(record,gameVo);
            List<Feature> featureList = featureMapper.selectByGameId(record.getId());
            if (featureList != null){
                gameVo.setFeatureList(featureList);
            }
            Type type = typeMapper.selectById(record.getTypeId());
            gameVo.setType(type);
            list.add(gameVo);
        });
        IPage<GameVo> voIPage = new Page<>();
        BeanUtil.copyProperties(gameIPage,voIPage);
        voIPage.setRecords(list);
        return voIPage;
    }

    /**
     * 根据id更新游戏
     *
     * @param gameDto
     * @return
     */
    @Override
    public boolean editById(GameDto gameDto) {
        Game game = new Game();
        BeanUtil.copyProperties(gameDto,game);
        return super.updateById(game);
    }

    /**
     * 根据id查询游戏详情
     *
     * @param id
     * @return
     */
    @Override
    public GameVo findOneById(Long id) {
        Game game = super.getById(id);
        GameVo gameVo = new GameVo();
        List<Feature> features = featureMapper.selectByGameId(id);
        gameVo.setFeatureList(features);
        Type type = typeMapper.selectById(game.getTypeId());
        gameVo.setType(type);
        return gameVo;
    }

    /**
     * 根据id删除游戏
     *
     * @param idsDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteByIds(IdsDto idsDto) {
        int i = gameMapper.deleteBatchIds(idsDto.getIds());
        if (i>0){
            QueryWrapper<GameFeature> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("game_id", idsDto.getIds());
            int delete = gameFeatureMapper.delete(queryWrapper);
            return delete>0;
        }
        return false;
    }

    /**
     * 搜索
     * 根据名称、公司、类型、特性、标题、描述、是否在线(网游、单机)、平台(端游、手游)
     *
     * @param queryDto
     * @return
     */
    @Override
    public IPage<GameVo> search(QueryDto queryDto) {
        Page<GameVo> page = new Page<>(queryDto.getCurrent(),queryDto.getSize());
        QueryGameDto queryGameDto = buildQuery(queryDto);
        // 所有字段都模糊查询
        List<GameVo> gameVos0 = gameMapper.queryByAllLike(page,queryGameDto);

        // TODO 拆字搜索 暂不需要(2020-12-17)
        // 插入feature集合
        setFeatureList(gameVos0);

        page.setRecords(gameVos0);
        return page;
    }

    /**
     * 每条记录查询feature集合
     * @param gameVos
     */
    private void setFeatureList(List<GameVo> gameVos){
        gameVos.forEach(gameVo -> {
            List<Feature> features = featureMapper.selectByGameId(gameVo.getId());
            gameVo.setFeatureList(features);
        });
    }

    /**
     * 根据搜索条件设置查询参数
     * @return
     */
    private QueryGameDto buildQuery(QueryDto query){
        QueryGameDto queryGameDto = new QueryGameDto();
        String condition = query.getCondition();
        String var0 = condition.toUpperCase();
        // 网游?
        for (String s : ONLINE_NAME_OFF) {
            if (var0.contains(s)){
                queryGameDto.setOnline(ONLINE_VALUE_OFF);
                break;
            }
        }
        // 单机?
        for (String s : ONLINE_NAME_ON) {
            if (var0.contains(s)){
                queryGameDto.setOnline(ONLINE_VALUE_ON);
                break;
            }
        }

        // 端游?
        for (String s : PLATFORM_NAME_PC) {
            if (var0.contains(s)){
                queryGameDto.setPlatform(PLATFORM_VALUE_PC);
                break;
            }
        }
        // 手游?
        for (String s : PLATFORM_NAME_MOBILE) {
            if (var0.contains(s)){
                queryGameDto.setPlatform(PLATFORM_VALUE_MOBILE);
                break;
            }
        }

        // 设置 游戏名称公司、描述、游戏标题、特性名称、类型名称
        queryGameDto.setGameName(condition);
        queryGameDto.setCompany(condition);
        queryGameDto.setDescription(condition);
        queryGameDto.setGameTitle(condition);
        queryGameDto.setFeatureName(condition);
        queryGameDto.setTypeName(condition);

        return queryGameDto;
    }
}
